<?php
namespace Plu\Library\Passport;


use Plu\Library\Security\Crypto;
use Plu\Library\Services\ServiceBase;
use Plu\qdh\Plugins\WechatCryptPlugin;

class Passport extends ServiceBase {
    private $redis;
    private $login_des;
    private $keys;

    private $uid;

    const CACHE_TIME = 86400;
    const TRY_TIME = 600;

    const TTL = 86400 * 30 * 1.5;

    public function __construct($redis_handler, $cache_handler) {
        $this->redis = $redis_handler;
        $this->cache = $cache_handler;

        $this->keys = $this->getKeysFromCache();
        list($encryptionKey, $validationKey) = $this->keys['new'];
        $this->login_des = new Crypto($encryptionKey, $validationKey);
    }

    /**
     * 获取登录加密密钥
     */
    private function getLoginEncryptionKeys() {
        list($a1, $a2, $a3, $a4) = $this->redis->zRange('plukeys', -4, -1);
        $keys = array(
            'old' => array(
                (strlen($a1) == 64 ? $a1 : $a2),
                (strlen($a1) == 32 ? $a1 : $a2),
            ),
            'new' => array(
                (strlen($a3) == 64 ? $a3 : $a4),
                (strlen($a3) == 32 ? $a3 : $a4),
            ),
            'updatetime' => time()
        );
        return $keys;
    }

    private function getUserId($encryption_uid, $tries = false) {

    }

    /**
     * 获取是否已登陆，如果登陆成功将直接返回uid
     *
     * @return mixed
     */
    public function isLogined() {
        if (!is_null($this->uid)) {
            return $this->uid;
        }

        $encryption_uid = $_COOKIE['p1u_id'];

        try {
            $ssoClient = $this->grpc->service("go.micro.srv.uc.sso");
            $reply = $ssoClient->VerifyLoginStatus((string)$encryption_uid);
            $data = $reply->getData();

            if ($data->getHasLogined()) {
                return $data->getUserId();
            } else {
                return false;
            }
        } catch (\Exception $e) {
            $this->logger->error($e->getMessage());
            return $this->getUserId($encryption_uid);
        }
    }

    /**
     * 获取当前登录用户的信息
     */
    public function getCurrentUserInfo() {
        if ($uid = $this->isLogined()) {
            return $this->getUserInfo($uid);
        }
    }

    private function getUserInfoFromRedis($uid) {
        if ($uid > 0) {
            $redis = $this->getRedis('login_cluster');
            $info = $redis->get(sprintf("u:%s", $uid));

            $info = json_decode($info, true);

            if (json_last_error() == \JSON_ERROR_NONE) {
                return $info;
            } else {
                return [];
            }
        } else {
            return [];
        }
    }

    /**
     * 获取指定的用户信息
     * @param Integer $uid 
     */
    public function getUserInfo($uid) {
        if ($uid > 0) {
            try {
                $userClient = $this->grpc->service("go.micro.srv.user");
                $info = $userClient->Info((int) $uid)->getData();

                if (!is_object($info)) {
                    return $this->getUserInfoFromRedis($uid);
                }

                return [
                    "uid"       => $info->getUserId(),
                    "nickname"  => $info->getNickname(),
                    "avatar"    => $info->getAvatar(),
                    "qq_avatar" => $info->getAvatar(),
                    "sex"       => $info->getSex(),
                    "geocode"   => $info->getGeocode(),
                    "signature" => $info->getSignature(),
                    "birthday"  => $info->getBirthday()
                ];
            } catch (\Exception $e) {
                return $this->getUserInfoFromRedis($uid);
            }
        } else {
            return [];
        }
    }


    private function getKeysFromCache($force = false) {
        $hashKey = sha1("__LoGinkeys__");
        $keys = $this->cache->get($hashKey, self::CACHE_TIME);
        if ($force || empty($keys) || !$this->cache->exists($hashKey, self::CACHE_TIME)) {
            $keys = $this->getLoginEncryptionKeys();
            $this->cache->save($hashKey, $keys, self::CACHE_TIME);
        }
        return $keys;
    }
}
